function graphMat=shockContributions(inStru,KFStru,sampleStru,graphStru,nameStru)
%% Shock Contributions
%
% Plot the decompositon of the Kalman filter srtcuture KFStru 
% either for the observables, in which case Y is an input, or selected
% states, in which case Y is empty. 
% Can plot either when feed only one shock or all except that shock. 
% Plots can be organized by shocks or by series. 
% 
%% 1. inStru       Structure with Inputs
% *.caseDecomp*  Decomposition
%
%               'single' plot series as explained by that shock 
%               'except' plot series as explained by ALL but that shock 
%
% *.orgBy*      'shocks' or 'series'               
%
% *.extract*    
%
% 
%% 2. KFStru, Kalman Filter Structure 
% 
% *.countObs* counterfactual for the observables, must add up to Y demeaned
% 
% *.countSt* counterfactual for the states 
% 
%% 3. NameStru 
%
% *.obsNames* Cell with names of observables in Z Matrix     
%
% *.stateNames* Cell with names of all states, i.e. rows of solution
% matrix 
%
% *.shockNames* Cell with names of all shocks          
%
%% 4. SampleStru
%
% *.sampleVec* Numeric Vector with Sample        
%
%% 5. graphStru 
%
% *.NYears* Number of years for which to plot X-axis        
%
% All additional inputs to bve used with plotColsorPages.m are assigned
% inside the code .
% 
% ===========================================================================================
%% 1. Determine if passing an observable, if so demean
posExtract=cellposition(inStru.extract,nameStru.stateNames);
decompOrig=KFStru.countSt(:,posExtract,:);
nameStru.colNames=inStru.extract;
nameStru.pageNames=nameStru.shockNames; 
%% 3. Type of Decomposition: single or except 
if strcmpi(inStru.caseDecomp,'single');
    decompMat=decompOrig;
    graphStru.suptitle=': contributions (deviations from SS)'; 
elseif strcmpi(inStru.caseDecomp,'except') || strcmpi(inStru.caseDecomp,'exclude')==1; 
    graphStru.suptitle=': contributions (deviations from SS)'; 
        decompMat=zeros(size(decompOrig));
        for ii=1:size(decompOrig,2);             
            for jj=1:size(decompOrig,3); 
                tempPos=setdiff( (1:size(decompMat,3))' , jj );
                decompMat(:,ii,jj)=squeeze(sum( decompOrig(:,ii,tempPos),3));                 
            end 
        end 
else
    error('Need define inStru.caseDecomp (string) single or except');
end 
[NR NC NP]=size(decompMat); 
%% 4. Plots by series (cols) or shocks (pages) 
if strcmpi(inStru.orgBy,'series');
    graphStru.orgBy='cols';
    NSub=NP; 
elseif strcmpi(inStru.orgBy,'shocks');
    graphStru.orgBy='pages';
    NSub=NC; 
else
    error('Need define inStru.orgBy (string) series or shocks');
end
%% 5. Assign Graphics defaults 
if isfield(graphStru,'NYears')==false || isempty(graphStru.NYears)
    if unique(fix(sampleStru.sampleVec)) <= 5
        graphStru.NYears=length(unique(fix(sampleStru.sampleVec)));
    else
        graphStru.NYears=5;
    end
end
junk=assignXAxis(sampleStru.sampleVec,5);
graphStru.suptitleFlush='right'; 
graphStru.xtickValues=junk.xtickValues;
graphStru.xtickLabels=junk.xtickLabels;
graphStru.legend=[];
graphStru.xOffset=0.1; 
graphStru.yOffset=0.01; 
graphStru.flagBoxOff=1; 
graphStru.lineWidths=1.5;
graphStru.color=[0 0 1]; 
graphStru.titleFontSize=11; 
graphStru.suptitleFontSize=12; 
graphStru.NFigCols=3;
graphStru.NFigRows=min(4,ceil(NSub/graphStru.NFigCols) );
graphStru.xaxis=sampleStru.sampleVec; 
graphMat=plotPages(decompMat,graphStru,nameStru);